maintaining the low-level equivalence of + and - methods). Running the
code in an instance method, however, gives undefined results if isa
points to a thin struct. If it points to a fat struct, we have come
full circle cvars look to instances like ivars look to classes.
(3)----------IN ANSWER TO A POST-------------------
Scott Meyer writes:
> > Currently this functionality is implemented with static
> > variables, but that approach unfortunately complicates
> > subclassing. It would seem to me that using static variables for
> > class management makes the language more complex than using class
> > variables.
>
> How does this complicate subclassing? The difficulty that I assume
> you are referring to is that subclasses cannot get at class variables
> (really static variables) unless the superclass provides methods
> to access the class variables. This may make you type more, but
> it hardly qualifies as a significant increase in complexity.
>
The one major semantic difference you have forgotten is that, like an
instance gets its own copies of ivars, a subclass gets its own copies
of class variables. So, the class variable "initCount" (which,say, is
incremented in the designated initializer of a class?) declared in
class A and referenced in the context of class A has a value. That
same variable referenced in the context of class B (A's subclass) has a
different value.
(4)----------A REMINDER ABOUT objc-runtime-------------------
There is a special list, gnu-objc-runtime for the discussion of
detailed issues pertaining to the implementation of the runtime support
system. Volume on gnu-objc has been light, so it's probably ok to send
everything to everyone. However, I urge you to keep the 4 special
purpose lists in mind and to start taking discussions there as you see
fit. Subscription requests to
gnu-objc-runtime-request@prep.ai.mit.edu
gnu-objc-map-request@prep.ai.mit.edu
gnu-objc-ibex-request@prep.ai.mit.edu
gnu-objc-coop-request@prep.ai.mit.edu
Date: Thu, 25 Feb 93 12:54:06 -0600
From: burchard@geom.umn.edu
To: athan@object.com (Andrew Athan)
Subject: Re: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
athan@object.com (Andrew Athan) writes:
> (1)----------SOMETHING TO AVOID----------------------------------
...
> + new
> {
> self = [Object getMemory];
> ivarFoo = 10;
> ivarBar = 20;
> return self;
> }
Most definitely...it makes my stomach turn to even look at it...
> Whatever syntax & semantics are used to reference cvars
> must not break this.
??? I hope that no one has ever written any code that uses this horrible hack/loophole. And if they have, the sooner such programs are exposed, the better, IMHO.
Lesson: like the Sunday school teacher said, do not play with your self.
(1)----------SOMETHING TO AVOID----------------------------------
Some notes on existing implementations of ObjC (back compatibility issues): Ivars are visible in class methods.
<< example >>
Whatever syntax & semantics are used to reference cvars must not break this.
snaroff:
We would really like to change this. Allowing instance variables to be accessed from class methods is EXTREMELY ERROR PRONE. I have been pulled into many debug situation where someone does:
+ new
{
if (someCondition)
self = [Object getMemory];
ivarFoo = 10;
ivarBar = 20;
return self;
}
If "someCondition" isn't true, self is not initialized and the class data structures in the Objective-C runtime are overwritten...causing things to break pretty quickly! Ever since allocation and initialization have been separated, this practice is much less common (within NeXT at least). Nevertheless, it should be disallowed by the language.
snaroff.
To: lupson@geom.umn.edu
Cc: gnu-objc@gnu.ai.mit.edu, rs05@gte.com
Subject: Re: Class Variables
In-Reply-To: Your message of "Thu, 25 Feb 93 11:24:52 CST."
<9302251724.AA00890@minkowski.geom.umn.edu>
Date: Thu, 25 Feb 93 13:57:20 -0500
From: rs05@gte.com
X-Mts: smtp
[Linus Upson (lupson@geom.umn.edu) suggests a way to
add class vars to the language, while hiding them
from instances except through class methods]
I think this is a rational approach.
It would be 'convenient' to have direct access to
those variables, but I agree with Linus that to do
so would lead to subclasses that are too dependent
on the superclass implementation.
also, I think his suggested syntax (below) reads well,
is quite succinct, is unambiguous, and is consistent with
the class/instance method designation scheme already
in place. beautiful it ain't, but it fits in very well.
--Russ
rs05@gte.com
> You can always share class variables with all the instances of that class
> But if you have class-instance variables, you can't "put the genie back in
> the bottle," and you're stuck with the encapsulation leakage.
Date: Thu, 25 Feb 93 15:09:06 CST
From: peter@tahiti.umhc.umn.edu
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
> [Linus Upson (lupson@geom.umn.edu) suggests a way to
> add class vars to the language, while hiding them
> from instances except through class methods]
> I think this is a rational approach.
ditto.
> ...
> also, I think his suggested syntax (below) reads well,
> is quite succinct, is unambiguous, and is consistent with
> the class/instance method designation scheme already
> in place. beautiful it ain't, but it fits in very well.
I agree, but... If we agree that cvars shouldn't be directly accessed by anyone besides that class, why should any other classes even know they exist other than the methods provided to read/change them? Cvars have no place in an interface file. They should be declared and used in the implementation file(s) for that class. How are they delimited? I don't know. The +/- would make sense if cvars and ivars had to be side by side, but if they will ALWAYS be in separate file(s) or atleast separate sections of code that may be enough.
ie.
@interface Foo:Object
{
// ivars
}
//cmethods
//imethods
@end
@implementation Foo
(?)
// cvars
(?)
//cmethods
//imethods
@end
where some person smarter than I would replace the '(?)' with an appropriate symbol. I like the '{'s but I know that this confilcts with published documents.... (Maybe I've been breaking rules on a NeXT for too long now...)
peter
peter@tahiti.umhc.umn.edu (Peter Eisch)
dig.
Date: Thu, 25 Feb 93 20:23:51 +0100
From: Peter Rasmussen <rasmus@dannug.dk>
To: gnu-objc@prep.ai.mit.edu
Subject: Re: Class Variables
Reply-To: rasmus@dannug.dk
In article ??? burchard@geom.umn.edu writes:
Hi ..
Concerning the desire to separate the definition of class and instance variables.
> We already define instance and class _methods_ in the same place, but
> use (+) and (-) to distinguish them. Why not do the same with
> instance and class variables (i.e., variables visible within the
> scope of instance and class methods, respectively)?
>
> @interface MyClass
> {
> @-
> // variables visible within instance methods
> id anInstanceVariable;
> @+
> // variables visible within class methods
> id aClassVariable;
> }
>
To me this depends upon how the concept of how class variables is defined.
1)
As I understand Objective-C class variables are not REALLY supported in the object system. Rather they are ordinary C-language variables layed out in global scope within the .o module of a class.
- To hold them encapsulated I do also define them
*static* like Stallman suggested.
- Since they as C-variables are outside of the ObjC object
system do NOT get inherited - I see no reason to declare
them in the class @interface.
1) They should not be accessed directly by users of class
2) Neither by subclass implementors
3) So why put their declaration into the @interface def.
2)
If class variables were to be introduced into the GNU Objective-C system object system, then things would be different. Then they would be inherited by subclasses and th
eir definition would be relevant to place into the @interface def.
> If we agree that cvars shouldn't be directly accessed by anyone besides
> that class, why should any other classes even know they exist other than
> the methods provided to read/change them? Cvars have no place in an
> interface file. They should be declared and used in the implementation
> file(s) for that class.
Inheritance. Class variables need to be declared in the interface file for the same reason that instance variables need to be declared there -- subclasses need to know what they inherit from their parents. That way you can subclass somebody else's object without having the source.
Linus Upson
The Geometry Center
lupson@geom.umn.edu
From: Kenneth Lerman <seltd!lerman@uunet.UU.NET>
X-Mailer: SCO System V Mail (version 3.2)
To: burchard@geom.umn.edu, corybant!scott@rmnug.org
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Date: Thu, 25 Feb 93 15:49:50 EST
Paul Burchard <burchard@geom.umn.edu> writes:
No, the difficulty is that with the use of static variables is that
subclasses get exactly the same *identical* variable. There is no
automatic way now for each subclass to transparently get access to a
distinct instantiation of the same conceptual variable.
For example, if a class needs to keep track of its instances, you
might try to define
@implementation BaseClass
static unsigned int instanceCount; // faked class variable
+ (unsigned int *)counter { return &instanceCount; }
But then subclasses will automatically inherit and modify BaseClass's
instance counter...ooops! Currently, in order to subclass this
behavior, each subclass would be required to define a new static
variable and to override the +counter method.
---------end of quote-------
What I've done to get "class variable" like behavior using statics is
George Mason Program on Social and Organizational Learning; Fairfax VA 22030
--
From: Steve_Naroff@NeXT.COM (Steve Naroff)
Date: Thu, 25 Feb 93 12:53:58 -0800
To: Kresten Krab Thorup <krab@iesd.auc.dk>
Subject: Re: Optimizing the GNU objc runtime [long]
Cc: gnu-objc@gnu.ai.mit.edu
Here is some data for a "typical" application on a NeXT (linked with the standard shared library of objects that we supply):
200-300 classes
6000-7000 method implementations
2000-3000 selectors (unique method names)
Many of these are classes are "private"...nevertheless, it is important that the runtime scale to support a system of this magnitude. It seems like you have already abandoned the idea of a per-class vector that has room for all possible selectors. This is good, since my "back of the envelope" calculation comes out to 3.2 megabytes to store all the caches (using 200 classes, 2000 selectors in the computation)! Let me know if I misinterpreted your proposal.
It sounds like the sparse array idea might reclaim much of this overhead. I would be interested in how much space that works out to be. The NeXT runtime typically consumes between 20-40 kilobytes for the per-class caches. The space occupied is proportional to the classes/methods used by the application. The simple rule is "pay if you play". In fact, even though there are 200-300 classes linked into an application, only 30-50% are typically used. I think any scalable system must incur mininal overhead (on a per-class basis) until the class is actually used.
Another method for doing dynamic dispatch (that is similar in spirit to your scheme) is to have a vector that is maintained on a per-app basis (not per-class) that has an entry for each selector. Each entry would contain a chain of classes that implement the selector...in practice, this chain is very short. A simple way to view this is go from the selector->class, rather than class->selector. I'm not convinced it statisfies your performance goals, but it is another way to look at the problem.
I think it is worthwhile goal to improve the performance of dispatching messages in Objective-C. Just be aware that it is a classic "time vs. space" problem...and saving time without carefully considering space doesn't work. Most computers are getting a lot faster without adding significantly more memory...this should influence the tradeoffs we make when designing the new runtime (my perspective, of course).
In the past, we have spent time optimizing memory utilization and improving locality of reference. This includes the data generated by the compiler as well as caches that are dynamically allocated (which are often "hot" for commonly used classes). We also developed a program called "objcopt" that improves launch time by building the selector hash table and "freeze drying" it in the executable for each shared library that we ship.
Given the portability goals of the project, I can't say that many of these apply to the GNU runtime...I just wanted to let you know what problems we work on wrt optimizing the NeXT Objective-C runtime.
btw...the NeXT runtime sends the "+initialize" lazily, was the change to execute before main() made intentionally?
>It ought to be possible to delay setting up a class's method dispatch
>table until the first time it is instantiated. Until then you need
>only the dispatch mechanism for the methods that act on the class
>rather than on an instance. I expect there will be much fewer
>operations of that sort.
This is easily done using the sparse array scheme. To do it, we would
initially install a dispatch table where the empty bucket is filled
with some function which installs the right dispatch table and forwards
the message. We will however need the ability to do forwarding.
Do you think we can find someone who'd like to implement a forwarding
primitive? At least the primitive one (__builtin_forward) we've been
talking about which does not allow one to do anything after the
forward. Using this we could implement the lazy dispatch table setup,
as well as lazy initialization.
/Kresten
Date: Thu, 25 Feb 93 23:37:06 -0800
From: John Jay Feiler <relief!jjfeiler@uu2.psi.com>
To: gnu-objc@gnu.ai.mit.edu
Subject: Re: Class Variables
Reply-To: relief!jjfeiler@uu2.psi.com
I think that the introduction of class variables into Obj-C is something that should definitely, be done, and I personally favor the @classVariable idea. However, there are ways to get around the lack of class variables in Obj-C. Here's what I do:
Say I want to have an object of type Foo associated with each class that inherits from class A
The HashTable fooHT is static, and only within the scope of the original Class A factory object, but since class methods are inherited, any subclass of A will call the +setFoo: and +getFoo methods above, and each factory object will have its own foo object associated with it.
Is it pretty? No. Does it work? Yes. At least until we get class variables implemented, anybody who really needs them can "fake" them.
Just my $0.02
John
Date: Thu, 25 Feb 93 23:52:34 -0800
From: John Jay Feiler <relief!jjfeiler@uu2.psi.com>
To: Steve_Naroff@NeXT.COM (Steve Naroff)
Subject: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
Reply-To: relief!jjfeiler@uu2.psi.com
If we don't allow a class method to access instance vars (or reassign self) how should we design objects which only have one instance, such as OpenPanel? I usually do the following:
@implementation Foo
static Foo *theFoo;
+ new
{
if(theFoo == nil)
{
self = theFoo = [super new];
/* initialize the Foo instance vars */
}
return self;
}
@end
This allows me to access the single object of class Foo with a simple message: [Foo new]
Faking this stuff with an alloc/init pair isn't very clean, and there is certainly use for Classes which only have one instance.
John
>
>
> Andrew writes:
>
> (1)----------SOMETHING TO
> AVOID---------------------------------- Some notes on
> existing implementations of ObjC (back compatibility
> issues): Ivars are visible in class methods.
>
> << example >>
>
> Whatever syntax & semantics are used to reference cvars
> must not break this.
>
> snaroff:
>
> We would really like to change this. Allowing instance
> variables to be accessed from class methods is EXTREMELY
> ERROR PRONE. I have been pulled into many debug situation
> where someone does:
>
> + new {
> if (someCondition)
> self = [Object getMemory];
>
> ivarFoo = 10; ivarBar = 20; return self; }
>
> If "someCondition" isn't true, self is not initialized
> and the class data structures in the Objective-C runtime
> are overwritten...causing things to break pretty quickly!
> Ever since allocation and initialization have been
> separated, this practice is much less common (within NeXT
> at least). Nevertheless, it should be disallowed by the
> language.
>
> snaroff.
>
From: billb@jupiter.fnbc.com (Bill Burcham)
Date: Fri, 26 Feb 93 09:40:44 -0600
To: lupson@geom.umn.edu
Subject: Re: Class Variables
Cc: gnu-objc@gnu.ai.mit.edu
Linus Upson <lupson@geom.umn.edu> writes:
> Peter Eisch <peter@tahiti.umhc.umn.edu> writes:
> > If we agree that cvars shouldn't be directly accessed by anyone besides
> > that class, why should any other classes even know they exist other than
> > the methods provided to read/change them? Cvars have no place in an
> > interface file. They should be declared and used in the implementation
> > file(s) for that class.
>
> Inheritance. Class variables need to be declared in the
> interface file for the same reason that instance
> variables need to be declared there -- subclasses need to
> know what they inherit from their parents. That way you
> can subclass somebody else's object without having the
> source.
>
> Linus Upson
> The Geometry Center
> lupson@geom.umn.edu
Please feel free to FLAME ME WITH IMPUNITY, but this illustrates the fact that it is _wrong_ to have only one interface file per class. There is _no_ reason to have _any_ instance variable definitions in an interface file -- other than for subclassing purposes. The language would be better if we had seperate files for the subclassing interface vs. "use" interface. To avoid duplication, we could #import the "use" interface into the subclassing interface. NeXT made the situation a _little_ better by providing the @class stuff so I don't have to #import irrelevant class interface files, but think about it: there is no such mechanism for forward declaration of protocols! So, if I want to associate a protocol with one of my ivars (o.k. GNU doesn't have protocols _yet_, but bear with me) then I have to #import that protocol definition -- even though the user of this class DOESN'T HAVE ANY NEED TO HAVE THAT PROTOCOL IN ITS SCOPE.
If we did this then a "use" interface would start to look suspiciously like (simply) a protocol. The only thing we would have to add to a protocol would be some way to get the compiler to see the external declaration of the Class. All of the stuff that we are currently putting in our interface would go into the subclassing interface.
Hi, (sorry If you get this twice - I had a Mail reject)
I'm not convinsed that class variables must be supported by the ObjC runtime system.
You seem to seek ENCAPSULATION and INNHERITANCE of class variables by adding language concepts for class variables.
In fact we have both already: by the static solution.
1) Encapsulation.
As static C-variables they are only visible within the class .o module. This protects class variables from other classes giving encapsulation between metaclass/metaclass and between class/metaclass. But with one convenient exception.
ObjC runs an IMPLICIT parallel metahierarchy of "Metaclasses" which enables the lower encapsulation shelters between class/metaclass PAIRS. The implicit metaclasses are only supposed to a have a single instance anyway (the class object) so why bother wrapping them into real objects and pay by raising real shelters between class/metaclass PAIRS.
>From the class side: The benefit of static vars for class variables is that you also can access them directly from instance methods (of the same class only) - not just class methods. If there were real class variables then instance methods would have to message to class objects to get the class variables.
>From the metaclass side: Not that much to gain from lower class/metaclass pair barriers.
2) Inheritance.
Here is my main point. Inheritance of class variables does infact already exist with the static solution.
> Currently, in order to subclass this behavior, each
> subclass would be required to define a new static
> variable and to override the +counter method.
>
> #define CV_SomeClass static int instanceCount; \ +
No - it is not necesseary to put NEW static class variables into each subclass. (I saw Kenneth use macro'es to make this easier). With this usage static becomes a bad and redundant solution - I agree.
Instead setup a subclass implementors interface for the static class variables. This means giving class methods to make them accessible. These class methods automatically gets inherited by your new IMPLICIT metaclass. And it is the subclass implementors responsibility to respect your subclass interface !!!
Let me give a simple example:
------------------------ BaseClass --------------
static int count; // the class variable
@implementation BaseClass:Object
{
}
+ initialize { count = 5; return self; }
+ (int)getCount { return count; }
+ setCount:(int)i { count = i; return self; }
@end
------------------------ ClassA --------------
@implementation ClassA:BaseClass
{
}
+ hereAmI { return self; }
@end
------------------------ Usage --------------
printf("Initialized %d\n, [BaseClass getCount]);
[ClassA setCount:10];
printf("New count %d\n", [ClassA getCount]);
------------------------ Execution --------------
Initialized 5
New count 10
So what is it that you seek by introducing class variables besides what can be achieved by static. OK - I need to set up class methods to access the STATIC class variables. But you would have to do that any way when wrapping the class variables into class-objects (from which there only exist a single anyway)
> Preferably, though, you would use the protocol that
> already exists. This will also subclass nicely:
>
> static Foo *theFoo;
> + new
> {
> if(!theFoo) theFoo = [[self alloc] init];
> return theFoo;
> }
> - init
> {
> if(![super init]) return nil;
> glub = 10;
> return self;
> }
>
(I should have said, this will subclass nicely modulo the ever-present class variable problem. To really subclass this without class variables, we must in addition use John's trick and replace references to theFoo with class methods which retrieve the correct "class var" from a static HashTable that maps classes -> "class var" pointers. Sorry for any confusion.)
> Your code does NOT implement "class variables"....it
> will give an incorrect answer for the next call to
> [BaseClass getCount]. The call to [ClassA setCount:10]
> has the "side effect" of also changing [BaseClass
> getCount].
Sure it does. This "side effect" was the whole intension. That ALL objects being kindOf BaseClass are able to share some non-redundant state.
This is "class variables" seen from the User Objects point of view
Holding User domain information.
> This is because there is no class variable inheritance
> here (inheritance of class *methods*, yes, of class
> *variables*, no). If "count" is a class variable
> that means I want to count each class separately.
I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
Lets take Kenneths example classes housekeeping how many instances they have. Sure this task would take a counting variable for each class. Separated yes - but why isolated ? Update of these "class variables" for counting ought to propagate within class methods.
If I instantiate eg. a View, I have also put one more object of all of its superclasses into play. So their instance counts should be updated also ...
static int count;
@implementation BaseClass:Object
{
}
+ initialize
{ count = 0; return self; }
+ (int)getCount
{ return count; }
+ bumpInstCnt
{ count++; return self; }
@end
------------------------------
static int count;
@implementation ClassA:BaseClass
{
}
+ bumpInstCnt
{ count++; return [super bumpInstCnt]; }
@end
And yes in this class object domain pt. of view it should be remembered to replicate class variables.
/Peter
From: Peter Eisch <peter@tahiti.umhc.umn.edu>
Date: Fri, 26 Feb 93 15:13:55 -0600
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
Peter Rasmussen <rasmus@dannug.dk> wrote:
>
> Paul Burchard wrote:
> > This is because there is no class variable inheritance
> > here (inheritance of class *methods*, yes, of class
> > *variables*, no). If "count" is a class variable
> > that means I want to count each class separately.
>
> I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
>
Put simply, the SCOPE of "Class Variables" should only be the class in which they are declared. They should not be visible to subclasses though the methods that manipulate them (if necessary) would be provided.
peter
peter@tahiti.umhc.umn.edu (Peter Eisch)
dig.
Date: Fri, 26 Feb 93 19:28:50 -0500
From: athan@object.com (Andrew Athan)
To: gnu-objc@prep.ai.mit.edu
Subject: Another interesting point (static)
A new user of Obj-C once was surprised by the following:
@implementation Foobar
- aMethod
{
static int x=10;
x=20;
}
@end
The guy had two instances of Foobar, and called aMethod on each. He was surprised to find that x==20 on entry into the second instance's call.
"Oh!" he said. "x is static in the same sense as in a static var in a function. I was expecting each instance to have a local static copy."
"... like an ivar, you mean?" someone replied.
Andrew Athan
Objective Technologies, Inc.
Date: Fri, 26 Feb 93 14:33:12 -0500
From: athan@object.com (Andrew Athan)
To: billb@jupiter.fnbc.com (Bill Burcham)
Subject: Re: Class Variables
Cc: lupson@geom.umn.edu, gnu-objc@gnu.ai.mit.edu
> Please feel free to FLAME ME WITH IMPUNITY, but this illustrates the fact that it is _wrong_ to have only one interface file per class
In general I vote down on any feature of a language which -requires- that I have multiple files. What are we trying to do, recreate Modula-2?!
>...
>If we did this then a "use" interface would start to look suspiciously like (simply) a protocol.
What you state can already be done with NeXT's objc. Just do this:
//this is my "Usage interface file"
@class ClassA
@protocol ClassAUsage
+ foobar;
- foobar;
@end
// this is my "Subclassing interface file"
@interface ClassA:Object < ClassAUsage >
{
...;
}
@end
// this is my "implementation file"
@implementation ClassA
+ foobar {}
- foobar {}
@end
> So, if I want to associate a protocol with one of my ivars (o.k. GNU doesn't have protocols _yet_, but bear with me) then I have to #import that protocol definition -- even though the user of this class DOESN'T HAVE ANY NEED TO HAVE THAT PROTOCOL IN ITS SCOPE.
This question is just one of "how many are too many" features? As a language definer, I can give you completely normalized declaration/implementation/specification features (normalized = no data repeated, no requirement to have data where you don't need it). As a language implementor (gcc) I can give you fully defered error management. Both are at a cost to complexity, which in the first case impacts at least readability (just from the simple standpoint of # of keywords, concepts to learn, etc.) and in the second at least compile time.
I don't dislike the way things are now in NeXT Obj-C. I do feel the protocol language extension needs work (there are problems stemming from the actual equivalience of + & - methods in obj-c, and from the -implementation- of the compile time "conformsTo:" checks being too restrictive. I feel that it's generally ok to have to include most of the .h's for the AppKit just to use even a simple class. Why? Because probably, in a large system, you'd find yourself having to spend a LOT of time making your .h's orthogonal anyway. Why bother? Just provide things like precomp headers, etc. to make the whole process faster. This way, you make the problems/errors/bugs less likely. Don't worry! Be Happy!
Andrew Athan
Objective Technologies, Inc.
Date: Fri, 26 Feb 93 13:50:51 -0500
From: athan@object.com (Andrew Athan)
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
See Peter's message following my sig. Unless I missunderstand him:
People keep missing the point! Let me make it clear: [This is in pseudo objc to keep things short. I think you understand]
Thus, you see that in a "real" cvar, **each class has its own copy automatically**. With a static variable **all subclasses share the same memory**. Just to prove that it can be implemented: one way is by having the ->isa metaclass struct for a class and its subclasses contain any declared realCvar's appended to the normal isa information. The code realCvar=10; really reads self->isa->realVar=10;.
Andrew Athan
Objective Technologies, Inc.
============================================
Peter Rasmussen writes:
> ...
> Here is my main point. Inheritance of class variables does infact already exist with the static solution.
> ...
> > Currently, in order to subclass this behavior, each
> > subclass would be required to define a new static
> > variable and to override the +counter method.
> >
> > #define CV_SomeClass static int instanceCount; \ +
> No - it is not necesseary to put NEW static class variables into each subclass. (I saw Kenneth use macro'es to make this easier). With this usage static becomes a bad and redundant solution - I agree.
>
> Instead setup a subclass implementors interface for the static class variables. This means giving class methods to make them accessible. These class methods automatically gets inherited by your new IMPLICIT metaclass. And it is the subclass implementors responsibility to respect your subclass interface !!!
> So what is it that you seek by introducing class variables besides what can be achieved by static. OK - I need to set up class methods to access the STATIC class variables. But you would have to do that any way when wrapping the class variables into class-objects (from which there only exist a single anyway)
>
> Regards
>
> Peter Rasmussen
>
Date: Fri, 26 Feb 93 19:18:51 -0500
From: athan@object.com (Andrew Athan)
To: rasmus@dannug.dk
Subject: Re: Class Variables
Cc: gnu-objc@prep.ai.mit.edu
> I get your point. Yes - There is also the other point of view of "Class variables". Where they hold information of their own - only relevant within the Class objects domain.
>
> Lets take Kenneths example classes housekeeping how many instances they have. Sure this task would take a counting variable for each class. Separated yes - but why isolated ? Update of these "class variables" for counting ought to propagate within class methods.
>
> If I instantiate eg. a View, I have also put one more object of all of its superclasses into play. So their instance counts should be updated also ...
>
The fact that static variables solve your example does not prove anything except that static variables are useful. The fact that static variables can be used to build class-variable like functionality also does not prove anything. Neither thing changes the fact that class variables are also useful: In the first case, they solve a different problem. In the second case, remember: C++ can be mapped onto C, and C onto assembler.
Andrew Athan
Objective Technologies, Inc.
Date: Sat, 27 Feb 93 18:52:42 -0800
From: John Jay Feiler <relief!jjfeiler@uu2.psi.com>
To: burchard@geom.umn.edu
Subject: Class Variables -- be careful!
Cc: gnu-objc@gnu.ai.mit.edu
Reply-To: relief!jjfeiler@uu2.psi.com
The only problem with this is that there isn't anything preventing someone from doing the following:
- someMethod
{
Foo *myFoo = [[Foo alloc] init];
.....
}
and getting a different instance of the Foo class. I guess if you override the +alloc and +allocFromZone: methods to raise an exception you can avoid this though.
As far as subclassing goes, using the theFoo = self = [super new] will subclass just as well as the init mechanism. Of course, if a class has only a single instance, then it's subclasses will likely do the same, and will require their own static variables to point to that instance.